﻿using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Newtonsoft.Json;
using PHMEE.Entities.BaseInfo.Points;
using PHMEE.Entities.BaseInfo.Units;
using PHMEE.Entities.DaqInfo.TdDevices;
using PHMEE.Entities.MqttDt.CollectPara;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text.Json;
using System.Xml.Linq;
using PHMEE.EnergyEfficiency;
using PHMEE.Entities.DaqInfo.Ams;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore.Modeling;

namespace PHMEE.EntityFrameworkCore.Extensions
{
    public static class BaseInfoModelCreatingExtension
    {
        public static void ConfigureBaseInfo(this ModelBuilder builder)
        {
            /* Configure your own tables/entities inside here */

            #region DaqInfo
            //采集定义类型
            builder.Entity<Category>(entity =>
            {
                entity.ToTable(PHMEEConsts.DbTablePrefix + PHMEEConsts.DtTablePrefix + "Categories", PHMEEConsts.DbSchema);
                entity.Property(x => x.Name)
                .IsRequired();
                entity.HasIndex(x => x.Name).IsUnique();
            });
            //阈值
            builder.Entity<Threshold>(entity =>
            {
                entity.ToTable(PHMEEConsts.DbTablePrefix + PHMEEConsts.DtTablePrefix + "Thresholds", PHMEEConsts.DbSchema);
                entity.Property(t => t.PointId).IsRequired();  // 确保每个Threshold都有一个PointId
                entity.HasOne(t => t.Category)
                      .WithMany()
                      .HasForeignKey(t => t.CategoryId);
            });
            //波形指标间隔
            builder.Entity<WaveInterval>(e =>
            {
                e.ToTable(PHMEEConsts.DbTablePrefix + "WaveIntervals", PHMEEConsts.DbSchema);
                e.Property(x => x.TimeSpan).IsRequired();
            });
            //流量计模版
            builder.Entity<FlowmeterTemplate>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "FlowmeterTemplates", PHMEEConsts.DbSchema);
                b.ConfigureByConvention();
            });
            #region 与TD数据库的结构创建和关联关系相关

            // 配置 TD数据库 实体
            builder.Entity<TdDatabase>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "TdDatabases", PHMEEConsts.DbSchema);
                b.ConfigureByConvention();

                // 设置名称为必填
                b.Property(x => x.Name).IsRequired();

                //删除数据库时会删除所有关联的超级表
                b.HasMany(d => d.SuperTables)
                 .WithOne(t => t.Database)
                 .HasForeignKey(t => t.DatabaseId)
                 .OnDelete(DeleteBehavior.Cascade);
            });

            //配置 超级表 实体
            builder.Entity<TdDeviceType>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "TdDeviceTypes", PHMEEConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(x => x.Name).IsRequired();
                b.Property(x => x.DatabaseId).IsRequired();

                //删除超级表会删除所有关联的属性及子表
                b.HasMany(x => x.Attributes)
                 .WithOne(x => x.TdDeviceType)
                 .OnDelete(DeleteBehavior.Cascade);

                b.HasMany(x => x.Instances)
                 .WithOne(x => x.TdDeviceType)
                 .OnDelete(DeleteBehavior.Cascade);
            });

            // 配置 超级表属性 实体
            builder.Entity<TdDeviceAttribute>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "TdDeviceAttributes", PHMEEConsts.DbSchema);
                b.Property(x => x.Name).IsRequired();
                b.ConfigureByConvention();
            });

            // 配置 子表 实体
            builder.Entity<TdDeviceInstance>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "TdDeviceInstances", PHMEEConsts.DbSchema);
                b.Property(x => x.InstanceName).IsRequired();
                b.ConfigureByConvention();
            });
            // 配置 TdDevicePointRelation 实体
            builder.Entity<TdDevicePointRelation>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "TdDevicePointRelations", PHMEEConsts.DbSchema);
                b.HasKey(e => new { e.TdDeviceInstanceId, e.PointId });

                // 配置 TdDeviceInstance 的一对多关系
                b.HasOne(e => e.TdDeviceInstance)
                 .WithMany()
                 .HasForeignKey(e => e.TdDeviceInstanceId)
                 .OnDelete(DeleteBehavior.Cascade); // 当 TdDeviceInstance 被删除时，删除其关联的关系

                // 配置 Point 的一对一关系
                b.HasOne(e => e.Point)
                 .WithOne()
                 .HasForeignKey<TdDevicePointRelation>(e => e.PointId)
                 .IsRequired(false); // 允许为空
            });
            builder.Entity<TdSqlScript>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "TdSqlScripts", PHMEEConsts.DbSchema);
            });

            #endregion

            #region Ams

            // Ams Digital（开关量）
            builder.Entity<DigitalConfig>(entity =>
            {
                entity.ToTable(PHMEEConsts.AmsTablePrefix + "DigitalConfig", PHMEEConsts.DbSchema);

                entity.Property(x => x.VesselId).IsRequired();

                entity.Property(x => x.TagName).HasMaxLength(128).IsRequired();

                entity.HasOne<Unit>()
                    .WithMany()
                    .HasForeignKey(x => x.UnitId)
                    .OnDelete(DeleteBehavior.Cascade);

                entity.HasOne<Vessel>()
                    .WithMany()
                    .HasForeignKey(x => x.VesselId)
                    .OnDelete(DeleteBehavior.Cascade);

            });

            #endregion Ams

            #endregion

            #region MqttDt
            //请求策略参数
            builder.Entity<SysPara>(entity =>
            {
                entity.ToTable(PHMEEConsts.DbTablePrefix + PHMEEConsts.DtTablePrefix + "SysParas", PHMEEConsts.DbSchema);
                entity.Property(x => x.IsOnline).HasDefaultValue(false);
                entity.Property(x => x.CollectorCode)
                .IsRequired();

                entity.HasMany(e => e.vibChannelParas)
                .WithOne(v => v.SysPara)
                .HasForeignKey(v => v.SysParaID)
                .OnDelete(DeleteBehavior.Cascade); // 设置级联删除;
            });
            //数采器扩展
            builder.Entity<SysParaExtend>(entity =>
            {
                entity.ToTable(PHMEEConsts.DbTablePrefix + PHMEEConsts.DtTablePrefix + "SysParaExtendeds", PHMEEConsts.DbSchema);
            });
            //振动传感器自诊断
            builder.Entity<Sensor>(entity =>
            {
                entity.ToTable(PHMEEConsts.DbTablePrefix + PHMEEConsts.DtTablePrefix + "Sensors", PHMEEConsts.DbSchema);
            });
            // 设置 CollectParameter 实体
            //builder.Entity<CollectParameter>(entity =>
            //{
            //    entity.ToTable(PHMEEConsts.DtTablePrefix + "CollectParameters", PHMEEConsts.DbSchema);
            //    entity.HasKey(e => e.Id);
            //    entity.HasMany(e => e.VibChannelList)
            //          .WithOne(v => v.CollectParameter)
            //          .HasForeignKey(v => v.CollectParameterId)
            //          .OnDelete(DeleteBehavior.Cascade); // 设置级联删除
            //    //entity.HasMany(e => e.TechChannelList).WithOne().HasForeignKey("CollectParameterId");
            //    //entity.HasMany(e => e.SpeedChannelList).WithOne().HasForeignKey("CollectParameterId");
            //    //entity.HasMany(e => e.TriggerList).WithOne().HasForeignKey("CollectParameterId");
            //    entity.Property(e => e.IsDeleted).HasDefaultValue(false);
            //});

            // 设置 VibChanneParal 实体
            builder.Entity<VibChannelPara>(entity =>
            {
                entity.ToTable(PHMEEConsts.DbTablePrefix + PHMEEConsts.DtTablePrefix + "VibChannels", PHMEEConsts.DbSchema);
                entity.HasKey(e => e.Id);
                entity.Property(e => e.SensType).HasDefaultValue(0); // 传感器类型默认为0-加速度
                entity.Property(e => e.CnstCurSrcState).HasDefaultValue(0); // 控制恒流源状态默认关闭
                entity.Property(e => e.SpeedDiffRate).HasDefaultValue(0f); // 转差率默认为0
                entity.Property(e => e.PolePairsNum).HasDefaultValue(1); // 极对数默认为1
                //entity.Property(e => e.IsDeleted).HasDefaultValue(false);
                //配置一对多关系
                entity.HasMany(e => e.VibParaList)
                  .WithOne(v => v.VibChannel)
                  .HasForeignKey(v => v.VibChannelId)
                  .OnDelete(DeleteBehavior.Cascade)
                  .IsRequired(false);

                //entity.HasOne(e => e.vibPara)
                //    .WithOne(v => v.VibChannel)
                //    .HasForeignKey<VibPara>(v => v.VibChannelId)
                //    .OnDelete(DeleteBehavior.Cascade)
                //    .IsRequired(false);
                //entity.HasMany(e => e.LimitParaList)
                //      .WithOne(v => v.VibChannel)
                //      .HasForeignKey(v => v.VibChannelId)
                //      .OnDelete(DeleteBehavior.Cascade)
                //      .IsRequired(false);
            });
            // 设置 VibPara 实体
            builder.Entity<VibPara>(entity =>
            {
                entity.ToTable(PHMEEConsts.DbTablePrefix + PHMEEConsts.DtTablePrefix + "VibParas", PHMEEConsts.DbSchema);
                entity.HasKey(e => e.Id);
                entity.Property(e => e.HighFreq).HasDefaultValue(0);//下限频率默认0
                entity.Property(e => e.Unit).HasDefaultValue("m/s^2");//工程单位默认（m/s^2）
                entity.Property(e => e.PlusLength).HasDefaultValue(0);//附加长度默认0
                entity.Property(e => e.Code).HasDefaultValue(VibIndexEnum.HighAccLongWave);//默认高频加速度
            });

            //// 设置 LimitPara 实体
            //builder.Entity<LimitPara>(entity =>
            //{
            //    entity.ToTable(PHMEEConsts.DtTablePrefix + "LimitParas", PHMEEConsts.DbSchema);
            //    entity.HasKey(e => e.Id);
            //});

            //// 设置 TechChannelPara 实体
            //builder.Entity<TechChannelPara>(entity =>
            //{
            //    entity.ToTable(PHMEEConsts.DtTablePrefix + "TechChannelParas", PHMEEConsts.DbSchema);
            //    entity.HasKey(e => e.Id);
            //    entity.Property(e => e.IsDeleted).HasDefaultValue(false);
            //});
            //// 设置 SpeedChannelPara 实体
            //builder.Entity<SpeedChannelPara>(entity =>
            //{
            //    entity.ToTable(PHMEEConsts.DtTablePrefix + "SpeedChannelParas", PHMEEConsts.DbSchema);
            //    entity.HasKey(e => e.Id);
            //    entity.Property(e => e.IsDeleted).HasDefaultValue(false);
            //});
            //// 设置 TriggerPara 实体
            //builder.Entity<TriggerPara>(entity =>
            //{
            //    entity.ToTable(PHMEEConsts.DtTablePrefix + "TriggerParas", PHMEEConsts.DbSchema);
            //    entity.HasKey(e => e.Id);
            //    entity.Property(e => e.IsDeleted).HasDefaultValue(false);
            //    entity.HasMany(e => e.TriggerLimitList).WithOne(p => p.TriggerPara).HasForeignKey("TriggerParaId");
            //});

            //// 设置 TriggerLimitPara 实体
            //builder.Entity<TriggerLimitPara>(entity =>
            //{
            //    entity.ToTable(PHMEEConsts.DtTablePrefix + "TriggerLimitParas", PHMEEConsts.DbSchema);
            //    entity.HasKey(e => e.Id);
            //});

            #endregion

            #region BaseInfo

            #region 公司

            builder.Entity<Company>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "Companies", PHMEEConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(x => x.Name).HasMaxLength(CompanyConst.MaxNameLength).IsRequired();
                b.Property(x => x.Info).HasMaxLength(CompanyConst.MaxInfoLength);

                b.Property(x => x.UserIds).HasConversion(v => JsonConvert.SerializeObject(v),
                    v => JsonConvert.DeserializeObject<List<Guid>>(v), ValueComparer.CreateDefault<List<Guid>>(false));

            });

            #endregion

            #region 船队

            builder.Entity<Fleet>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "Fleets", PHMEEConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(x => x.Name).HasMaxLength(FleetConst.MaxNameLength).IsRequired();
            });

            #endregion

            #region 船舶

            builder.Entity<Vessel>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "Vessels", PHMEEConsts.DbSchema)
                 .HasDiscriminator<string>("Discriminator")
                 .HasValue<Bulker>(nameof(Bulker))
                 .HasValue<Container>(nameof(Container))
                 .HasValue<Tanker>(nameof(Tanker));

                b.ConfigureByConvention();

                b.Property(x => x.DerivedPropertiesJson).HasConversion(v => JsonConvert.SerializeObject(v),
                    v => JsonConvert.DeserializeObject<Dictionary<string, object>>(v), ValueComparer.CreateDefault<Dictionary<string, object>>(false));

                b.Property(x => x.Name).HasMaxLength(VesselConst.MaxNameLength).IsRequired();

                b.Property(x => x.NameEn).HasMaxLength(VesselConst.MaxNameLength).IsRequired();

                b.Property(x => x.IMO).HasMaxLength(VesselConst.MaxIMOLength).IsRequired();

                b.Property(x => x.CallSign).HasMaxLength(VesselConst.MaxCallSignLength);

                b.Property(x => x.FlagState).HasMaxLength(VesselConst.MaxFlagStateLength);

                b.Property(x => x.ClassificationSociety).HasMaxLength(VesselConst.MaxClassificationSocietyLength);

                b.HasMany(x => x.Units).WithOne().IsRequired().HasForeignKey(x => x.VesselId);
            });

            #endregion

            #region 机组

            builder.Entity<Unit>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "Units", PHMEEConsts.DbSchema)
                 .HasDiscriminator<string>("Discriminator")
                 .HasValue<BallastPumpUnit>(nameof(BallastPumpUnit))
                 .HasValue<CombustionAirBlowerUnit>(nameof(CombustionAirBlowerUnit))
                 .HasValue<FuelOilSeparatorUnit>(nameof(FuelOilSeparatorUnit))
                 .HasValue<LubricatingOilPumpUnit>(nameof(LubricatingOilPumpUnit))
                 .HasValue<LubricatingOilSepaUnit>(nameof(LubricatingOilSepaUnit))
                 .HasValue<MainEngineUnit>(nameof(MainEngineUnit))
                 .HasValue<MainGeneratorUnit>(nameof(MainGeneratorUnit))
                 .HasValue<SeaWaterPumpUnit>(nameof(SeaWaterPumpUnit))
                 .HasValue<StartingAirCompressUnit>(nameof(StartingAirCompressUnit));

                b.ConfigureByConvention();

                b.Property(x => x.DerivedPropertiesJson).HasConversion(v => JsonConvert.SerializeObject(v),
                    v => JsonConvert.DeserializeObject<Dictionary<string, object>>(v), ValueComparer.CreateDefault<Dictionary<string, object>>(false));

                b.Property(x => x.Name).HasMaxLength(UnitConst.MaxNameLength).IsRequired();

                b.Property(x => x.NameEn).HasMaxLength(UnitConst.MaxNameLength).IsRequired();

                b.Property(x => x.Area).HasMaxLength(UnitConst.MaxAreaLength);

                b.HasMany(x => x.Equipments).WithOne().IsRequired().HasForeignKey(x => x.UnitId);
            });

            #endregion

            #region 设备

            builder.Entity<Equipment>(b =>
            {

                b.ToTable(PHMEEConsts.DbTablePrefix + "Equipments", PHMEEConsts.DbSchema)
                 .HasDiscriminator<string>("Discriminator")
                 .HasValue<AsynElectricMotor>(nameof(AsynElectricMotor))
                 .HasValue<CentrifugalFan>(nameof(CentrifugalFan))
                 .HasValue<CentrifugalPump>(nameof(CentrifugalPump))
                 .HasValue<FuelOilSeparatorGear>(nameof(FuelOilSeparatorGear))
                 .HasValue<LubricatingOilSeparatorGear>(nameof(LubricatingOilSeparatorGear))
                 .HasValue<MainEngine>(nameof(MainEngine))
                 .HasValue<MainGenerator>(nameof(MainGenerator))
                 .HasValue<MainGeneratorDiesel>(nameof(MainGeneratorDiesel))
                 .HasValue<ReciprocatingCompressor>(nameof(ReciprocatingCompressor))
                 .HasValue<ShaftSystem>(nameof(ShaftSystem))
                 .HasValue<Turbocharger>(nameof(Turbocharger));

                b.ConfigureByConvention();

                b.Property(x => x.DerivedPropertiesJson).HasConversion(v => JsonConvert.SerializeObject(v),
                    v => JsonConvert.DeserializeObject<Dictionary<string, object>>(v), ValueComparer.CreateDefault<Dictionary<string, object>>(false));

                b.Property(x => x.Name).HasMaxLength(EquipmentConst.MaxNameLength).IsRequired();

                b.Property(x => x.NameEn).HasMaxLength(EquipmentConst.MaxNameLength).IsRequired();

                b.Property(x => x.Model).HasMaxLength(EquipmentConst.MaxModelLength);

                b.Property(x => x.Manufacturer).HasMaxLength(EquipmentConst.MaxManufacturerLength);

                b.HasMany(x => x.Components).WithOne().IsRequired().HasForeignKey(x => x.EquipmentId);

            });

            #endregion

            #region 部件

            builder.Entity<Component>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "Components", PHMEEConsts.DbSchema)
                 .HasDiscriminator<string>("Discriminator")
                 .HasValue<CouplerShaftComponent>(nameof(CouplerShaftComponent))
                 .HasValue<CylinderComponent>(nameof(CylinderComponent))
                 .HasValue<MainBearComponent>(nameof(MainBearComponent))
                 .HasValue<MiddleBearComponent>(nameof(MiddleBearComponent))
                 .HasValue<MiddleShaftComponent>(nameof(MiddleShaftComponent))
                 .HasValue<PropellerShaftComponent>(nameof(PropellerShaftComponent))
                 .HasValue<SternBearComponent>(nameof(SternBearComponent))
                 .HasValue<SternShaftComponent>(nameof(SternShaftComponent))
                 .HasValue<ThrustBearComponent>(nameof(ThrustBearComponent))
                 .HasValue<ThrustShaftComponent>(nameof(ThrustShaftComponent));

                b.ConfigureByConvention();

                b.Property(x => x.DerivedPropertiesJson).HasConversion(v => JsonConvert.SerializeObject(v),
                    v => JsonConvert.DeserializeObject<Dictionary<string, object>>(v), ValueComparer.CreateDefault<Dictionary<string, object>>(false));

                b.Property(x => x.Name).HasMaxLength(ComponentConst.MaxNameLength).IsRequired();

                b.Property(x => x.NameEn).HasMaxLength(ComponentConst.MaxNameLength).IsRequired();

                b.Property(x => x.Model).HasMaxLength(ComponentConst.MaxModelLength);
            });

            #endregion

            #region 测点

            builder.Entity<Point>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "Points", PHMEEConsts.DbSchema)
                 .HasDiscriminator<string>("Discriminator")
                 .HasValue<AcceleratePoint>(nameof(AcceleratePoint))
                 .HasValue<AnglePoint>(nameof(AnglePoint))
                 .HasValue<CurrentPoint>(nameof(CurrentPoint))
                 .HasValue<DisplacementPoint>(nameof(DisplacementPoint))
                 .HasValue<DraftPoint>(nameof(DraftPoint))
                 .HasValue<FlowPoint>(nameof(FlowPoint))
                 .HasValue<FrequencyPoint>(nameof(FrequencyPoint))
                 .HasValue<FuelConsumptionPoint>(nameof(FuelConsumptionPoint))
                 .HasValue<FuelTypePoint>(nameof(FuelTypePoint))
                 .HasValue<LatitudePoint>(nameof(LatitudePoint))
                 .HasValue<LevelPoint>(nameof(LevelPoint))
                 .HasValue<LoadPoint>(nameof(LoadPoint))
                 .HasValue<LongitudePoint>(nameof(LongitudePoint))
                 .HasValue<MainEngineStatusPoint>(nameof(MainEngineStatusPoint))
                 .HasValue<PowerFactorPoint>(nameof(PowerFactorPoint))
                 .HasValue<PowerPoint>(nameof(PowerPoint))
                 .HasValue<PressurePoint>(nameof(PressurePoint))
                 .HasValue<RevSpeedPoint>(nameof(RevSpeedPoint))
                 .HasValue<SpeedPoint>(nameof(SpeedPoint))
                 .HasValue<TemperaturePoint>(nameof(TemperaturePoint))
                 .HasValue<TorquePoint>(nameof(TorquePoint))
                 .HasValue<ViscosityPoint>(nameof(ViscosityPoint))
                 .HasValue<VoltagePoint>(nameof(VoltagePoint));

                b.ConfigureByConvention();

                b.Property(x => x.DerivedPropertiesJson).HasConversion(v => JsonConvert.SerializeObject(v),
                    v => JsonConvert.DeserializeObject<Dictionary<string, object>>(v), ValueComparer.CreateDefault<Dictionary<string, object>>(false));

                b.Property(x => x.Name).HasMaxLength(PointConst.MaxNameLength).IsRequired();

                b.Property(x => x.NameEn).HasMaxLength(PointConst.MaxNameLength).IsRequired();

                b.Property(x => x.OwnerType).HasMaxLength(PointConst.MaxOwnerTypeLength);

                b.Property(x => x.Unit).HasMaxLength(PointConst.MaxUnitLength);
            });

            #endregion

            #region 维保建议

            builder.Entity<MainenanceAdvice>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "MainenanceAdvices", PHMEEConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(x => x.Code).HasMaxLength(MaintenanceAdviceConst.MaxCodeLength).IsRequired();
            });

            #endregion

            #region 轴承库厂商

            builder.Entity<BearFactory>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "BearFactories", PHMEEConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(x => x.Id).ValueGeneratedOnAdd().Metadata.SetBeforeSaveBehavior(Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Save);
                b.Property(x => x.Name).HasMaxLength(BearConst.MaxFactoryNameLength).IsRequired();
                b.HasMany(x => x.BearLibs).WithOne().IsRequired().HasForeignKey(x => x.BearFactoryId);
            });

            #endregion

            #region 轴承库

            builder.Entity<BearLib>(b =>
            {
                b.ToTable(PHMEEConsts.DbTablePrefix + "BearLibs", PHMEEConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(x => x.Model).HasMaxLength(BearConst.MaxLibModelLength).IsRequired();
            });

            #endregion

            #endregion

            #region 能效 1.0 合并

#nullable enable

            builder.Entity<VesselEeConfig>(entity =>
            {
                entity.ToTable(PHMEEConsts.EeTablePrefix + "VesselEeConfigs", PHMEEConsts.DbSchema);

                entity.ConfigureByConvention();

                entity.HasKey(x => x.Id);

                entity.Property(x => x.FleetId).IsRequired();
                entity.Property(x => x.Name).IsRequired();
                entity.Property(x => x.IMO).IsRequired();
                entity.Property(x => x.VesselType).IsRequired();
                entity.Property(x => x.NT).IsRequired();
                entity.Property(x => x.GT).IsRequired();
                entity.Property(x => x.DWT).IsRequired();
                entity.Property(x => x.FuelTypes)
                    .HasColumnType("json")
                    .HasConversion(
                        v => System.Text.Json.JsonSerializer.Serialize(v, (JsonSerializerOptions?)null),
                        v => System.Text.Json.JsonSerializer.Deserialize<List<FuelType>>(v, (JsonSerializerOptions?)null)!,
                        new ValueComparer<List<FuelType>>(
                            (c1, c2) => new HashSet<FuelType>(c1!).SetEquals(c2!), // Compare as sets
                            c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), // Compute hash code
                            c => c.ToList())
                    );
                entity.Property(x => x.EEDI).IsRequired();
                entity.Property(x => x.EEXI).IsRequired();
                entity.Property(x => x.IceClass).IsRequired();
                entity.Property(x => x.FtTanker).IsRequired();
                entity.Property(x => x.Fi).IsRequired();
                entity.Property(x => x.Fm).IsRequired();
                entity.Property(x => x.Fc).IsRequired();
                entity.Property(x => x.FiVSE).IsRequired();
                entity.Property(x => x.VToCIIs)
                    .HasColumnType("json")
                    .HasConversion(
                        v => System.Text.Json.JsonSerializer.Serialize(v, (JsonSerializerOptions?)null),
                        v => System.Text.Json.JsonSerializer.Deserialize<List<VToCII>>(v, (JsonSerializerOptions?)null)!,
                        new ValueComparer<List<VToCII>>(
                            (c1, c2) => new HashSet<VToCII>(c1!).SetEquals(c2!), // Compare as sets
                            c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), // Compute hash code
                            c => c.ToList())
                    ).IsRequired();
                entity.Property(x => x.CIIDefaultBound)
                    .HasColumnType("json")
                    .HasConversion(
                        v => System.Text.Json.JsonSerializer.Serialize(v, (JsonSerializerOptions?)null),
                        v => System.Text.Json.JsonSerializer.Deserialize<CIIDefaultBound>(v, (JsonSerializerOptions?)null)!,
                        new ValueComparer<CIIDefaultBound>(
                            (c1, c2) => Math.Abs(c1!.Min - c2!.Min) < 0.0001f &&
                                        Math.Abs(c1.Max - c2.Max) < 0.0001f, // Compare as sets
                            c => HashCode.Combine(c.Min, c.Max), // Compute hash code
                            c => c)
                    ).IsRequired();

                entity.Property(x => x.IsFuelAutoCollect).IsRequired();

                entity.Property(x => x.IsGpsAutoCollect).IsRequired();
            });

            builder.Entity<CiiReductionFactor>(b =>
            {
                b.ToTable($"{PHMEEConsts.EeTablePrefix}CiiReductionFactors", PHMEEConsts.DbSchema);

                b.ConfigureByConvention();

                b.HasKey(e => e.Id);
                b.HasIndex(e => e.Year).IsUnique();
                b.Property(e => e.Year).IsRequired();
                b.Property(e => e.Z).IsRequired();
            });

            // TODO: LogAbstract 与 BunkerReport 数据同步日志表，相关逻辑迁移到 MySQL 且新数据同步程序支持后，不再需要这些表
            builder.Entity<TimeSeriesDataLog>(b =>
            {
                b.ToTable($"{PHMEEConsts.EeTablePrefix}TimeSeriesDataLogs", PHMEEConsts.DbSchema);

                b.ConfigureByConvention();

                b.HasKey(e => e.Id);

                b.Property(e => e.VesselId).IsRequired();

                b.Property(e => e.Ts).IsRequired();

                b.Property(e => e.SyncDataType).IsRequired();

                b.Property(e => e.OperationType).IsRequired();

                b.Property(e => e.OperationTime).IsRequired();

                b.Property(e => e.IsSynced).IsRequired();
            });

            // TODO: LogAbstract 与 BunkerReport 数据同步墓碑表，相关逻辑迁移到 MySQL 且新数据同步程序支持后，不再需要这些表
            builder.Entity<TimeSeriesTombstones>(b =>
            {
                b.ToTable($"{PHMEEConsts.EeTablePrefix}TimeSeriesTombstones", PHMEEConsts.DbSchema);

                b.ConfigureByConvention();

                b.HasKey(e => e.Id);

                b.Property(e => e.Id).ValueGeneratedOnAdd();

                b.Property(e => e.Ts).IsRequired();

                b.Property(e => e.VesselId).IsRequired();

                b.Property(e => e.SyncDataType).IsRequired();

                b.Property(e => e.DeletedAt).IsRequired();

                b.HasIndex(e => new { e.VesselId, e.Ts, e.SyncDataType });
            });

            builder.Entity<OvdPort>(b =>
            {
                b.ToTable($"{PHMEEConsts.EeTablePrefix}OvdPorts", PHMEEConsts.DbSchema);

                b.ConfigureByConvention();

                b.HasKey(x => x.Id);

                b.Property(x => x.Name).HasMaxLength(128).IsRequired();

                b.Property(x => x.Code).HasMaxLength(128).IsRequired();

                b.Property(x => x.Identifier).HasMaxLength(128).IsRequired();

                b.HasIndex(x => x.Identifier).IsUnique();
            });

#nullable disable

            #endregion
        }
    }
}
